package com.golxen.framework.db;


import com.golxen.utils.LogUtil;
import com.golxen.utils.YmlUtil;
import com.mysql.cj.util.LogUtils;
import org.slf4j.Logger;


import java.sql.Connection;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * 数据库连接池管理类
 * 根据配置创建连接池
 *
 *  可以调用getInstance()方法访问本类的唯一实例
 * 
 */
public class DBPoolManager {
    private static DBPoolManager instance; // 唯一实例
    private Hashtable<String, IDBPool> pools = new Hashtable<String, IDBPool>();// 多种连接池

    /**
     * 单例模式建构私有函数以防止其它对象创建本类实例
     */
    private DBPoolManager() {
        this.init();
    }

    /**
     * 采用单例模式，返回唯一实例.如果是第一次调用此方法,则创建实例
     */
    public static synchronized DBPoolManager getInstance() {
        if (instance == null) {
            instance = new DBPoolManager();
        }
        return instance;
    }

    /**
     * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 限制,则创建并返回新连接
     */
    public Connection getConnection(String name) {
        IDBPool dbPool = pools.get(name);
        if (dbPool != null) {
            // 获取JDBC连接池"
            return dbPool.getConnection();
        }
        LogUtil.DB.error(String.format("no find db link pool,name:%s", name));
        return null;
    }

    /**
     * 关闭所有连接,撤销驱动程序的注册
     */
    public synchronized void closeFallow() {
        Enumeration<IDBPool> allPools = pools.elements();
        while (allPools.hasMoreElements()) {
            IDBPool pool = allPools.nextElement();
            pool.shutdown();
        }
    }

    public void addPools(String url,String user,String password) {
        createPools(url,user,password);
    }

    /**
     * 读取属性完成初始化
     */
    private void init() {
        // 创建连接池
        createPools(YmlUtil.getString("serverdb.url"),YmlUtil.getString("serverdb.username"),YmlUtil.getString("serverdb.password"));
    }

    /**
     * 根据指定属性创建连接池实例.
     *
     */
    private void createPools(String url,String user,String password) {
        String poolName = url.substring(url.lastIndexOf("/")+1, url.indexOf("?"));

        if (pools.containsKey(poolName)) {
            LogUtil.DB.info("repeated load db link pool:{},URL:{} finish！", poolName, url);
            return;
        }

        IDBPool pool = new DruidDBPool(url, user, password);
        LogUtil.DB.info(String.format("load db link pool:%s,URL:%s finish！", poolName, url));
        pools.put(poolName, pool);

    }

    /**
     * 解密数据库连接字符串
     * 
     * @param str 数据库连接解密key，一般不会变动，写在程序中
     */
    private String decrypt(String str) {
        return str;
    }

    /**
     * 加密数据库连接字符串格式：url|user|password|maxconn
     * 
     * @param str 数据库连接加密key，一般不会变动，写在程序中
     * @return
     */
    String encrypt(String str) {
        return str;
    }

}
